package main

import "fmt"

func main() {
	list := []int{1,2,3,4,5,6,7,8,9}
	list1 := []int{2,41,43,14,23}
	s := summation(list, len(list)-1) //len(list)必须减1，否则flag超出了切片索引的范围
	s1 := summation(list1,len(list1)-1)
	fmt.Println(s)
	fmt.Println(s1)

	s2 := accumulation(list,len(list)-1)
	s3 := accumulation(list1,len(list1)-1)
	fmt.Println(s2)
	fmt.Println(s3)

	//正统函数式编程
	a := adder2(0)
	for i := 0; i < 10; i++ {
		var s int
		s,a = a(i)
		fmt.Println(s)
	}
}

//因为go语言数组中的方法中没有index此类的取出索引值
//所以使用了flag变量来作为递归条件
//此方法没有使用基线条件

func summation(list []int,flag int) int {
	if flag >= 0 {
		return list[flag] + summation(list,flag-1)
	}
	return 0
}

func accumulation(list []int, flag int) int {
	if flag < 0 {  //基线条件
		return 0
	}else {			//递归条件
		return list[flag] + summation(list,flag-1)
	}
}

//附加知识：
//正统函数式编程：
//不可变性：不能有状态，只有常量和函数
//函数只能有一个参数
//正统函数式编程：（闭包使用）

type iAdder func(int) (int,iAdder)

func adder2(base int) iAdder {
	return func(v int)(int,iAdder){
		return base + v,adder2(base+v)
	}
}